﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyWatermark
{
    public static class DctTransformer
    {
        // 预计算余弦表
        private static readonly double[,,,] CosTable = PrecomputeCosTables();
        private const int N = 8;

        private static double[,,,] PrecomputeCosTables()
        {
            var table = new double[N, N, N, N];
            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < N; j++)
                {
                    for (int x = 0; x < N; x++)
                    {
                        for (int y = 0; y < N; y++)
                        {
                            table[i, j, x, y] =
                                Math.Cos((2 * x + 1) * i * Math.PI / (2 * N)) *
                                Math.Cos((2 * y + 1) * j * Math.PI / (2 * N));
                        }
                    }
                }
            }
            return table;
        }
        // 二维DCT变换
        // 优化后的DCT
        public static void Dct(double[,] data)
        {
            double alpha = Math.Sqrt(2.0 / N);
            double[,] temp = new double[N, N];

            // 行变换
            for (int y = 0; y < N; y++)
            {
                for (int i = 0; i < N; i++)
                {
                    double sum = 0;
                    for (int x = 0; x < N; x++)
                    {
                        sum += data[x, y] * CosTable[i, 0, x, 0];
                    }
                    temp[i, y] = sum * alpha * ((i == 0) ? 1 / Math.Sqrt(2) : 1);
                }
            }

            // 列变换
            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < N; j++)
                {
                    double sum = 0;
                    for (int y = 0; y < N; y++)
                    {
                        sum += temp[i, y] * CosTable[j, 0, y, 0];
                    }
                    data[i, j] = sum * alpha * ((j == 0) ? 1 / Math.Sqrt(2) : 1);
                }
            }
        }


        public static void Idct(double[,] data)
        {
            double alpha = Math.Sqrt(2.0 / N);
            double[,] temp = new double[N, N];

            // 行变换（一维IDCT）
            for (int y = 0; y < N; y++)
            {
                for (int x = 0; x < N; x++)
                {
                    double sum = 0;
                    for (int i = 0; i < N; i++)
                    {
                        double ci = (i == 0) ? 1 / Math.Sqrt(2) : 1;
                        sum += ci * data[i, y] * CosTable[i, 0, x, 0];
                    }
                    temp[x, y] = sum * alpha;
                }
            }

            // 列变换（一维IDCT）
            for (int x = 0; x < N; x++)
            {
                for (int y = 0; y < N; y++)
                {
                    double sum = 0;
                    for (int j = 0; j < N; j++)
                    {
                        double cj = (j == 0) ? 1 / Math.Sqrt(2) : 1;
                        sum += cj * temp[x, j] * CosTable[j, 0, y, 0];
                    }
                    data[x, y] = sum * alpha;
                }
            }
        }
    }
}
